Overview

Once installed Argo CD has one built-in admin user that has full access to the system. It is recommended to use admin user only for initial configuration and then switch to local users or configure SSO integration.

Local users/accounts (v1.5)

The local users/accounts feature serves two main use-cases:

  • Auth tokens for Argo CD management automation. It is possible to configure an API account with limited permissions and generate an authentication token. Such token can be used to automatically create applications, projects etc.
  • Additional users for a very small team where use of SSO integration might be considered an overkill. The local users don’t provide advanced features such as groups, login history etc. So if you need such features it is strongly recommended to use SSO.

Note

When you create local users, each of those users will need additional RBAC rules set up, otherwise they will fall back to the default policy specified by policy.default field of the argocd-rbac-cm ConfigMap.

The maximum length of a local account’s username is 32.

Create new user

New users should be defined in argocd-cm ConfigMap:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. # add an additional local user with apiKey and login capabilities
  11. # apiKey - allows generating API keys
  12. # login - allows to login using UI
  13. accounts.alice: apiKey, login
  14. # disables user. User is enabled by default
  15. accounts.alice.enabled: "false"

Each user might have two capabilities:

  • apiKey - allows generating authentication tokens for API access
  • login - allows to login using UI

Disable admin user

As soon as additional users are created it is recommended to disable admin user:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. admin.enabled: "false"

Manage users

The Argo CD CLI provides set of commands to set user password and generate tokens.

  • Get full users list
  1. argocd account list
  • Get specific user details
  1. argocd account get --account <username>
  • Set user password
  1. argocd account update-password \
  2. --account <name> \
  3. --current-password <current-user-password> \
  4. --new-password <new-user-password>
  • Generate auth token
  1. # if flag --account is omitted then Argo CD generates token for current user
  2. argocd account generate-token --account <username>

Failed logins rate limiting

Argo CD rejects login attempts after too many failed in order to prevent password brute-forcing. The following environments variables are available to control throttling settings:

  • ARGOCD_SESSION_MAX_FAIL_COUNT: Maximum number of failed logins before Argo CD starts rejecting login attempts. Default: 5.

  • ARGOCD_SESSION_FAILURE_WINDOW_SECONDS: Number of seconds for the failure window. Default: 300 (5 minutes). If this is set to 0, the failure window is disabled and the login attempts gets rejected after 10 consecutive logon failures, regardless of the time frame they happened.

  • ARGOCD_SESSION_MAX_CACHE_SIZE: Maximum number of entries allowed in the cache. Default: 1000

  • ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT: Limits max number of concurrent login requests. If set to 0 then limit is disabled. Default: 50.

SSO

There are two ways that SSO can be configured:

Dex

Argo CD embeds and bundles Dex as part of its installation, for the purpose of delegating authentication to an external identity provider. Multiple types of identity providers are supported (OIDC, SAML, LDAP, GitHub, etc…). SSO configuration of Argo CD requires editing the argocd-cm ConfigMap with Dex connector settings.

This document describes how to configure Argo CD SSO using GitHub (OAuth2) as an example, but the steps should be similar for other identity providers.

1. Register the application in the identity provider

In GitHub, register a new application. The callback address should be the /api/dex/callback endpoint of your Argo CD URL (e.g. https://argocd.example.com/api/dex/callback).

Register OAuth App

After registering the app, you will receive an OAuth2 client ID and secret. These values will be inputted into the Argo CD configmap.

OAuth2 Client Config

2. Configure Argo CD for SSO

Edit the argocd-cm configmap:

  1. kubectl edit configmap argocd-cm -n argocd
  • In the url key, input the base URL of Argo CD. In this example, it is https://argocd.example.com
  • In the dex.config key, add the github connector to the connectors sub field. See Dex’s GitHub connector documentation for explanation of the fields. A minimal config should populate the clientID, clientSecret generated in Step 1.
  • You will very likely want to restrict logins to one or more GitHub organization. In the connectors.config.orgs list, add one or more GitHub organizations. Any member of the org will then be able to login to Argo CD to perform management tasks.
  1. data:
  2. url: https://argocd.example.com
  3. dex.config: |
  4. connectors:
  5. # GitHub example
  6. - type: github
  7. id: github
  8. name: GitHub
  9. config:
  10. clientID: aabbccddeeff00112233
  11. clientSecret: $dex.github.clientSecret # Alternatively $<some_K8S_secret>:dex.github.clientSecret
  12. orgs:
  13. - name: your-github-org
  14. # GitHub enterprise example
  15. - type: github
  16. id: acme-github
  17. name: Acme GitHub
  18. config:
  19. hostName: github.acme.com
  20. clientID: abcdefghijklmnopqrst
  21. clientSecret: $dex.acme.clientSecret # Alternatively $<some_K8S_secret>:dex.acme.clientSecret
  22. orgs:
  23. - name: your-github-org

After saving, the changes should take affect automatically.

NOTES:

  • There is no need to set redirectURI in the connectors.config as shown in the dex documentation. Argo CD will automatically use the correct redirectURI for any OAuth2 connectors, to match the correct external callback URL (e.g. https://argocd.example.com/api/dex/callback)

Existing OIDC Provider

To configure Argo CD to delegate authenticate to your existing OIDC provider, add the OAuth2 configuration to the argocd-cm ConfigMap under the oidc.config key:

  1. data:
  2. url: https://argocd.example.com
  3. oidc.config: |
  4. name: Okta
  5. issuer: https://dev-123456.oktapreview.com
  6. clientID: aaaabbbbccccddddeee
  7. clientSecret: $oidc.okta.clientSecret
  8. # Optional set of OIDC scopes to request. If omitted, defaults to: ["openid", "profile", "email", "groups"]
  9. requestedScopes: ["openid", "profile", "email", "groups"]
  10. # Optional set of OIDC claims to request on the ID token.
  11. requestedIDTokenClaims: {"groups": {"essential": true}}
  12. # Some OIDC providers require a separate clientID for different callback URLs.
  13. # For example, if configuring Argo CD with self-hosted Dex, you will need a separate client ID
  14. # for the 'localhost' (CLI) client to Dex. This field is optional. If omitted, the CLI will
  15. # use the same clientID as the Argo CD server
  16. cliClientID: vvvvwwwwxxxxyyyyzzzz

Note

The callback address should be the /auth/callback endpoint of your Argo CD URL (e.g. https://argocd.example.com/auth/callback).

Requesting additional ID token claims

Not all OIDC providers support a special groups scope. E.g. Okta, OneLogin and Microsoft do support a special groups scope and will return group membership with the default requestedScopes.

Other OIDC providers might be able to return a claim with group membership if explicitly requested to do so. Individual claims can be requested with requestedIDTokenClaims, see OpenID Connect Claims Parameter for details. The Argo CD configuration for claims is as follows:

  1. oidc.config: |
  2. requestedIDTokenClaims:
  3. email:
  4. essential: true
  5. groups:
  6. essential: true
  7. value: org:myorg
  8. acr:
  9. essential: true
  10. values:
  11. - urn:mace:incommon:iap:silver
  12. - urn:mace:incommon:iap:bronze

For a simple case this can be:

  1. oidc.config: |
  2. requestedIDTokenClaims: {"groups": {"essential": true}}

Configuring a custom logout URL for your OIDC provider

Optionally, if your OIDC provider exposes a logout API and you wish to configure a custom logout URL for the purposes of invalidating any active session post logout, you can do so by specifying it as follows:

  1. oidc.config: |
  2. name: example-OIDC-provider
  3. issuer: https://example-OIDC-provider.com
  4. clientID: xxxxxxxxx
  5. clientSecret: xxxxxxxxx
  6. requestedScopes: ["openid", "profile", "email", "groups"]
  7. requestedIDTokenClaims: {"groups": {"essential": true}}
  8. logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}}

By default, this would take the user to their OIDC provider’s login page after logout. If you also wish to redirect the user back to Argo CD after logout, you can specify the logout URL as follows:

  1. ...
  2. logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}

You are not required to specify a logoutRedirectURL as this is automatically generated by ArgoCD as your base ArgoCD url + Rootpath

Note

The post logout redirect URI may need to be whitelisted against your OIDC provider’s client settings for ArgoCD.

SSO Further Reading

Sensitive Data and SSO Client Secrets

You can use the argocd-secret to store any sensitive data. ArgoCD knows to check the keys under data in the argocd-secret secret for a corresponding key whenever a value in a configmap starts with $. This can be used to store things such as your clientSecret. * Any values which start with $ will : - If value is in form of $<secret>:a.key.in.k8s.secret, look to a key in K8S <secret> of the same name (minus the $), and reads it value. - Otherwise, look to a key in argocd-secret of the same name (minus the $), to obtain the actual value. This allows you to store the clientSecret as a kubernetes secret. Kubernetes secrets must be base64 encoded. To base64 encode your secret, you can run printf RAW_STRING | base64.

Data should be base64 encoded before it is added to argocd-secret. You can do so by running printf RAW_SECRET_STRING | base64.

Example

argocd-secret:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: argocd-secret
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-secret
  8. app.kubernetes.io/part-of: argocd
  9. type: Opaque
  10. data:
  11. ...
  12. # Store client secret like below.
  13. # Ensure the secret is base64 encoded
  14. oidc.auth0.clientSecret: <client-secret-base64-encoded>
  15. ...

argocd-cm:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. ...
  11. oidc.config: |
  12. name: Auth0
  13. clientID: aabbccddeeff00112233
  14. # Reference key in argocd-secret
  15. clientSecret: $oidc.auth0.clientSecret
  16. ...

Alternative

If you want to store sensitive data in another Kubernetes Secret, instead of argocd-secret. ArgoCD knows to check the keys under data in your Kubernetes Secret for a corresponding key whenever a value in a configmap starts with $, then your Kubernetes Secret name and : (colon).

Syntax: $<k8s_secret_name>:<a_key_in_that_k8s_secret>

NOTE: Secret must have label app.kubernetes.io/part-of: argocd

Example

another-secret:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: another-secret
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/part-of: argocd
  8. type: Opaque
  9. data:
  10. ...
  11. # Store client secret like below.
  12. # Ensure the secret is base64 encoded
  13. oidc.auth0.clientSecret: <client-secret-base64-encoded>
  14. ...

argocd-cm:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. ...
  11. oidc.config: |
  12. name: Auth0
  13. clientID: aabbccddeeff00112233
  14. # Reference key in another-secret (and not argocd-secret)
  15. clientSecret: $another-secret:oidc.auth0.clientSecret # Mind the ':'
  16. ...